/*  
* Copyright (c) 2010, James Daniello
* This project is licensed under the 'New BSD' license.
* The full text of the license can be found in the root
* directory under the filename "LICENSE"
*/
package src.network;


/**
* This code is a reusable ping service that can be applied to the communications class for both
* the client and server end of PICAIU. Each client is connected to a repsective object on the server and
* each end can house one of these for pinging each other and repsonding if a pong is not returned.
*/
public class PICAIUPingService extends Thread{

  //if active ping every 'pingTime' in milliseconds
  private boolean running = true;
  public static final int pingTime = 12/*seconds*/ * 1000;
  
  //time of last ping and whether or not a ping has already been sent
  private long lastPingTime=0;
  private boolean pingSent=false;
  
  //parent object
  private PICAIUCanPing parent;
  
  /**
  * Creates a new instance of this ping service and sets the parent object
  */
  public PICAIUPingService(PICAIUCanPing parentIn){
    parent=parentIn;
  }
  
  /**
  * This update method is called from the parent object and handles sending a new ping if
  * enough time has lapsed or notifying the parent that a pong has not been received if
  * enough time has passed. Every <pingTime> in milliseconds it sends a ping, or notifies
  * that one has not been received.
  */
  public void update(){
    
    try{
      //if client is still connected and enough time has passed
      if(parent.isConnected()&&System.currentTimeMillis()-lastPingTime>pingTime){
        //if a ping has not been sent (or has been returned)
        if(!pingSent){
          pingSent=true;
          lastPingTime = System.currentTimeMillis(); //used to measure ping time
          parent.ping();
        //else a pong has not been returned
        }else{
          parent.pongNotReceived();
        }
      }
    }catch (Exception e){}
  }

  /**
  * Sets this ping service as no longer running
  */
  protected void clear(){
    running = false;
  }
  
  /**
  * Called from the parent object when a pong has been received over the network. This method 
  * is inherited in it's parent from the interface PICAIUCanPing
  */
  protected void pongReceived(){
    pingSent=false;
    long pingMeasurement = System.currentTimeMillis()-lastPingTime;
    if(parent.isVerbose()){
      System.out.println("Ping time is "+pingMeasurement+" ms");
    }
  }
  
}